package command

import (
	"github.com/spf13/cobra"
	"strconv"
	"strings"
)

func NewTikvOperator() *cobra.Command {
	c := &cobra.Command{
		Use:   "tikv",
		Short: "tikv operator commands",
	}
	c.AddCommand(NewGetValueByKey())
	c.AddCommand(NewPutKeyValues())
	c.AddCommand(NewDelValueByKey())
	c.AddCommand(NewScanKeyValues())
	c.AddCommand(NewDelAllKey())
	return c
}

func NewGetValueByKey() *cobra.Command {
	c := &cobra.Command{
		Use:   "get [key]",
		Short: "get the value by key",
		Args:  cobra.MinimumNArgs(1),
		Run:   getValueBykey,
	}
	return c
}

func NewPutKeyValues() *cobra.Command {
	c := &cobra.Command{
		Use:   "put [key:value,key:value]",
		Short: "put the key:value s",
		Args:  cobra.MinimumNArgs(1),
		Run:   putKeyValue,
	}
	return c
}

func NewDelValueByKey() *cobra.Command {
	c := &cobra.Command{
		Use:   "del [key key]",
		Short: "del by keys",
		Args:  cobra.MinimumNArgs(1),
		Run:   delValueBykey,
	}
	return c
}

func NewScanKeyValues() *cobra.Command {
	c := &cobra.Command{
		Use:   "scan [beginkey:endkey limitnum]",
		Short: "scan by beginkey:endkey limitnum",
		Args:  cobra.MinimumNArgs(1),
		Run:   scanKeyValue,
	}
	return c
}

func NewDelAllKey() *cobra.Command {
	c := &cobra.Command{
		Use:   "delall [beginkey:endkey]",
		Short: "delall beginkey:endkey 0:0 delall",
		Args:  cobra.MinimumNArgs(1),
		Run:   delallKey,
	}
	return c
}

func getValueBykey(cmd *cobra.Command, args []string) {
	if len(args) == 1 {
		kv, err := GetInstance(cmd).TxGet([]byte(args[0]))
		if err != nil {
			cmd.Println(err)
			return
		}
		cmd.Println(string(kv.K)+":"+string(kv.V))
		return
	}
	cmd.Println(cmd.UsageString())
}

func putKeyValue(cmd *cobra.Command, args []string) {
	if len(args) > 0 {
		var kvlist []KV
		for _, kv := range args {
			tmp := strings.Split(kv, ":")
			if len(tmp) < 2{
				cmd.Println("use key:value")
				return
			}
			kvlist = append(kvlist, KV{K: []byte(tmp[0]), V: []byte(tmp[1])})
		}
		GetInstance(cmd).TxPut(kvlist)
		return
	}
	cmd.Println(cmd.UsageString())
}

func delValueBykey(cmd *cobra.Command, args []string) {
	if len(args) > 0 {
		var keylist [][]byte
		for _, key := range args {
			keylist = append(keylist, []byte(key))
		}

		GetInstance(cmd).TxDelete(keylist)
		return
	}

	cmd.Println(cmd.UsageString())
}

func scanKeyValue(cmd *cobra.Command, args []string) {
	if len(args) == 2 {
		tmp := strings.Split(args[0], ":")
		if len(tmp) < 2{
			cmd.Println("beginkey:endkey limitnum")
			return
		}
		limit, err := strconv.Atoi(args[1])
		if err != nil{
			cmd.Println("beginkey:endkey limitnum")
			return
		}
		rsp, err := GetInstance(cmd).TxScan([]byte(tmp[0]), []byte(tmp[1]), limit)
		if err != nil{
			cmd.Println(err)
			return
		}
		for _, kv := range rsp{
			cmd.Println(string(kv.K)+":"+string(kv.V))
		}
		return
	}
	cmd.Println(cmd.UsageString())
}

func delallKey(cmd *cobra.Command, args []string) {
	if len(args) == 1 {
		tmp := strings.Split(args[0], ":")
		if len(tmp) < 2{
			cmd.Println(cmd.UsageString())
			return
		}
		if(tmp[0] == "0") {
			tmp[0] = ""
		}
		if(tmp[1] == "0") {
			tmp[1] = ""
		}
		num, err := GetInstance(cmd).Delall([]byte(tmp[0]), []byte(tmp[1]))
		if err != nil{
			cmd.Println(err)
			return
		}
		cmd.Println(num)
		return
	}
	cmd.Println(cmd.UsageString())
}